package com.have.blog.xo.service.admin.impl;

import com.github.pagehelper.PageHelper;

import com.have.blog.base.enums.AdminMenuEnum;
import com.have.blog.base.enums.BlogStatus;
import com.have.blog.model.api.CommonPage;
import com.have.blog.model.mapper.TCategoryMenuMapper;
import com.have.blog.model.models.TCategoryMenu;
import com.have.blog.model.models.TCategoryMenuExample;
import com.have.blog.utils.MyStringUtils;
import com.have.blog.utils.ResultUtils;
import com.have.blog.xo.constant.MessageConstant;
import com.have.blog.xo.constant.SysConstant;
import com.have.blog.xo.service.cache.AdminCacheService;
import com.have.blog.xo.service.admin.AdminCategoryMenuService;
import com.have.blog.xo.vo.CategoryMenuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
@SuppressWarnings("all")
public class AdminCategoryMenuServiceImpl implements AdminCategoryMenuService {
    @Autowired
    private TCategoryMenuMapper categoryMenuMapper;
    @Autowired
    private AdminCacheService cacheService;

    @Override
    public String getList(CategoryMenuVo categoryMenuVo) {
        Map<String, Object> resultMap = new HashMap<>();
        PageHelper.startPage(categoryMenuVo.getCurrentPage(), categoryMenuVo.getPageSize());
        TCategoryMenuExample example = new TCategoryMenuExample();
        TCategoryMenuExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(categoryMenuVo.getKeyword()) && !StringUtils.isEmpty(categoryMenuVo.getKeyword().trim())) {
            criteria.andNameLike("%" + categoryMenuVo.getKeyword() + "%");
        }
        if (categoryMenuVo.getMenuLevel() != 0) {
            criteria.andMenuLevelEqualTo(categoryMenuVo.getMenuLevel());
        }
        List<TCategoryMenu> categoryMenuList = categoryMenuMapper.selectByExample(example);
        CommonPage<TCategoryMenu> categoryMenuCommonPage = CommonPage.restPage(categoryMenuList);
        List<TCategoryMenu> list = categoryMenuCommonPage.getList();
        List<String> uidList = new ArrayList<>();
        list.forEach(item -> {
            if (!StringUtils.isEmpty(item.getParentUid())) {
                uidList.add(item.getParentUid());
            }
        });

        if (!CollectionUtils.isEmpty(uidList)) {
            TCategoryMenuExample example1 = new TCategoryMenuExample();
            example1.createCriteria()
                    .andUidIn(uidList);
            List<TCategoryMenu> parentList = categoryMenuMapper.selectByExample(example1);

            Map<String, TCategoryMenu> map = new HashMap<>();
            parentList.forEach(item -> {
                map.put(item.getUid(), item);
            });

            list.forEach( item -> {
                if (!StringUtils.isEmpty(item.getParentUid())) {
                    item.setParentCategoryMenu(map.get(item.getParentUid()));
                }
            });
            resultMap.put(SysConstant.OTHER_DATA, parentList);
        }
        resultMap.put(SysConstant.DATA, categoryMenuCommonPage);
        return ResultUtils.result(SysConstant.SUCCESS, resultMap);
    }

    @Override
    public String getAllList(String keyword) {
        List<TCategoryMenu> list = getAllCategoryMenu(keyword);

        // 查询二级菜单
        List<TCategoryMenu> childList = getChildCategoryMenu(list);

        // 获取三级按钮
        List<TCategoryMenu> buttonList = getChildButton(childList);

        Map<String, List<TCategoryMenu>> map = new HashMap<>();
        buttonList.forEach(item -> {
            if (!StringUtils.isEmpty(item.getParentUid())) {
                List<TCategoryMenu> tempList = map.get(item.getParentUid());
                if (tempList == null) {
                    tempList = new ArrayList<TCategoryMenu>();
                }
                tempList.add(item);
                map.put(item.getParentUid(), tempList);
            }
        });

        // 给二级菜单设置三级按钮
        childList.forEach(item -> {
            List<TCategoryMenu> tempList = map.get(item.getUid());
            if (tempList != null) {
                Collections.sort(tempList, new Comparator<TCategoryMenu>() {
                    @Override
                    public int compare(TCategoryMenu o1, TCategoryMenu o2) {
                        return (o2.getSort() - o1.getSort());
                    }
                });
            }
            item.setChildCategoryMenu(tempList);
        });
        // 给一级菜单设置二级菜单
        for (TCategoryMenu parentItem : list) {
            List<TCategoryMenu> tempList = new ArrayList<>();
            for (TCategoryMenu item : childList) {
                if (item.getParentUid().equals(parentItem.getUid())) {
                    tempList.add(item);
                }
            }
            Collections.sort(tempList, new Comparator<TCategoryMenu>() {
                @Override
                public int compare(TCategoryMenu o1, TCategoryMenu o2) {
                    return (o2.getSort() - o1.getSort());
                }
            });
            parentItem.setChildCategoryMenu(tempList);
        }
        return ResultUtils.result(SysConstant.SUCCESS, list);
    }

    @Override
    public String getAllButton(String keyword) {
        TCategoryMenuExample example = new TCategoryMenuExample();
        TCategoryMenuExample.Criteria criteria = example.createCriteria()
                .andStatusEqualTo(BlogStatus.ENABLE.getStatus())
                .andMenuLevelEqualTo(2);
        if (!StringUtils.isEmpty(keyword)) {
            criteria.andUidEqualTo(keyword);
        }
        example.setOrderByClause("sort desc");
        // 获得所有二级菜单
        List<TCategoryMenu> list = categoryMenuMapper.selectByExample(example);

        List<String> uids = new ArrayList<>();
        list.forEach(item -> {
            uids.add(item.getUid());
        });

        example.clear();
        example.createCriteria()
                .andStatusEqualTo(BlogStatus.ENABLE.getStatus())
                .andParentUidIn(uids);
        List<TCategoryMenu> childList = categoryMenuMapper.selectByExample(example);

        Set<String> secondUidSet = new HashSet<>();
        Map<String, List<TCategoryMenu>> map = new HashMap<>();
        childList.forEach(item -> {
            if (!StringUtils.isEmpty(item.getParentUid())) {
                secondUidSet.add(item.getParentUid());
                List<TCategoryMenu> tempList = map.get(item.getParentUid());
                if (tempList == null) {
                    tempList = new ArrayList<>();
                }
                tempList.add(item);
                map.put(item.getParentUid(), tempList);
            }
        });

        // 过滤不在Button列表中的二级菜单
        List<TCategoryMenu> secondCategoryMenuList = new ArrayList<>();
        for (TCategoryMenu secondCategoryMenu : list) {
            for (String uid : secondUidSet) {
                if (secondCategoryMenu.getUid().equals(uid)) {
                    secondCategoryMenuList.add(secondCategoryMenu);
                    break;
                }
            }
        }

        // 给二级菜单设置三级按钮
        secondCategoryMenuList.forEach(item -> {
            if (map.get(item.getUid()) != null) {
                List<TCategoryMenu> tempList = map.get(item.getUid());
                Collections.sort(tempList, new Comparator<TCategoryMenu>() {
                    @Override
                    public int compare(TCategoryMenu o1, TCategoryMenu o2) {
                        return o2.getSort() - o1.getSort();
                    }
                });
                item.setChildCategoryMenu(tempList);
            }
        });
        return ResultUtils.successWithData(list);
    }

    public List<TCategoryMenu> getAllCategoryMenu(String keyword) {
        TCategoryMenuExample example = new TCategoryMenuExample();
        TCategoryMenuExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(keyword) && !StringUtils.isEmpty(keyword.trim())) {
            criteria.andUidEqualTo(keyword);
        }
        example.setOrderByClause("sort desc");
        criteria.andMenuLevelEqualTo(1)
                .andStatusEqualTo(BlogStatus.ENABLE.getStatus())
                .andMenuTypeEqualTo(AdminMenuEnum.MENU.getType());
        List<TCategoryMenu> list = categoryMenuMapper.selectByExample(example);
        return list;
    }

    public List<TCategoryMenu> getChildCategoryMenu(List<TCategoryMenu> list) {
        List<String> idList = new ArrayList<>();
        list.forEach(item -> {
            if (!StringUtils.isEmpty(item.getUid())) {
                idList.add(item.getUid());
            }
        });
        TCategoryMenuExample childExample = new TCategoryMenuExample();
        childExample.createCriteria()
                .andParentUidIn(idList)
                .andStatusEqualTo(BlogStatus.ENABLE.getStatus());
        List<TCategoryMenu> childList = categoryMenuMapper.selectByExample(childExample);
        return childList;
    }

    public List<TCategoryMenu> getChildButton(List<TCategoryMenu> list) {
        List<String> secondMenuUidList = new ArrayList<>();
        list.forEach(item -> {
            if (!StringUtils.isEmpty(item.getUid())) {
                secondMenuUidList.add(item.getUid());
            }
        });

        TCategoryMenuExample buttonExample = new TCategoryMenuExample();
        buttonExample.createCriteria()
                .andStatusEqualTo(BlogStatus.ENABLE.getStatus())
                .andParentUidIn(secondMenuUidList);
        List<TCategoryMenu> buttonList = categoryMenuMapper.selectByExample(buttonExample);
        return buttonList;
    }

    @Override
    public String addCategoryMenu(CategoryMenuVo categoryMenuVO) {
        if (categoryMenuVO.getMenuLevel() == SysConstant.ONE) {
            categoryMenuVO.setParentUid("");
        }
        TCategoryMenu categoryMenu = new TCategoryMenu();
        categoryMenu.setParentUid(categoryMenuVO.getParentUid());
        categoryMenu.setSort(categoryMenuVO.getSort());
        categoryMenu.setIcon(categoryMenuVO.getIcon());
        categoryMenu.setSummary(categoryMenuVO.getSummary());
        categoryMenu.setMenuLevel(categoryMenuVO.getMenuLevel());
        categoryMenu.setMenuType(categoryMenuVO.getMenuType());
        categoryMenu.setName(categoryMenuVO.getName());
        categoryMenu.setUrl(categoryMenuVO.getUrl());
        categoryMenu.setIsShow(categoryMenuVO.getIsShow());
        categoryMenu.setIsJumpExternalUrl(categoryMenuVO.getIsJumpExternalUrl());
        categoryMenu.setUid(MyStringUtils.getUUID());
        categoryMenu.setUpdateTime(new Date());
        categoryMenu.setCreateTime(new Date());
        categoryMenuMapper.insertSelective(categoryMenu);
        cacheService.deleteResourceList("*");
        return ResultUtils.successWithMessage(MessageConstant.INSERT_SUCCESS);
    }

    @Override
    public String editCategoryMenu(CategoryMenuVo categoryMenuVO) {
        if (StringUtils.isEmpty(categoryMenuVO.getUid()) && StringUtils.isEmpty(categoryMenuVO.getUid().trim())) {
            return ResultUtils.errorWithMessage(MessageConstant.PARAM_INCORRECT);
        }
        TCategoryMenu categoryMenu = categoryMenuMapper.selectByPrimaryKey(categoryMenuVO.getUid());
        categoryMenu.setName(categoryMenuVO.getName());
        categoryMenu.setMenuLevel(categoryMenuVO.getMenuLevel());
        categoryMenu.setParentUid(categoryMenuVO.getParentUid());
        categoryMenu.setSummary(categoryMenuVO.getSummary());
        categoryMenu.setIcon(categoryMenuVO.getIcon());
        categoryMenu.setIsJumpExternalUrl(categoryMenuVO.getIsJumpExternalUrl());
        categoryMenu.setUrl(categoryMenuVO.getUrl());
        categoryMenu.setIsShow(categoryMenuVO.getIsShow());
        categoryMenu.setSort(categoryMenuVO.getSort());
        categoryMenu.setMenuType(categoryMenuVO.getMenuType());
        categoryMenu.setUpdateTime(new Date());
        categoryMenuMapper.updateByPrimaryKeySelective(categoryMenu);
        cacheService.deleteResourceList("*");
        return ResultUtils.successWithMessage(MessageConstant.UPDATE_SUCCESS);
    }

    @Override
    public String stickCategoryMenu(CategoryMenuVo categoryMenuVO) {
        if (StringUtils.isEmpty(categoryMenuVO.getUid()) && StringUtils.isEmpty(categoryMenuVO.getUid().trim())) {
            return ResultUtils.errorWithMessage(MessageConstant.PARAM_INCORRECT);
        }
        TCategoryMenu categoryMenu = categoryMenuMapper.selectByPrimaryKey(categoryMenuVO.getUid());
        TCategoryMenuExample example = new TCategoryMenuExample();
        TCategoryMenuExample.Criteria criteria = example.createCriteria();
        if (categoryMenu.getMenuLevel() == 2 || categoryMenu.getMenuType() == AdminMenuEnum.BUTTON.getType()) {
            criteria.andParentUidEqualTo(categoryMenu.getParentUid());
        }
        criteria.andMenuLevelEqualTo(categoryMenu.getMenuLevel());
        example.setOrderByClause("sort desc");
        List<TCategoryMenu> list = categoryMenuMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            return ResultUtils.errorWithMessage(MessageConstant.PARAM_INCORRECT);
        }

        TCategoryMenu top = list.get(0);
        System.out.println(top.getName());
        System.out.println(top.getSort());
        categoryMenu.setSort(top.getSort() + 1);
        categoryMenuMapper.updateByPrimaryKeySelective(categoryMenu);
        return ResultUtils.successWithMessage(MessageConstant.OPERATION_SUCCESS);
    }

    @Override
    public String deleteCategoryMenu(CategoryMenuVo categoryMenuVO) {
        TCategoryMenuExample example = new TCategoryMenuExample();
        example.createCriteria()
                .andParentUidEqualTo(categoryMenuVO.getUid())
                .andStatusEqualTo(BlogStatus.ENABLE.getStatus());
        long count = categoryMenuMapper.countByExample(example);
        if (count > 0) { // 如果此菜单下还有子菜单不允删除
            return ResultUtils.errorWithMessage(MessageConstant.CHILDREN_MENU_UNDER_THIS_MENU);
        }
        TCategoryMenu categoryMenu = new TCategoryMenu();
        categoryMenu.setUid(categoryMenuVO.getUid());
        categoryMenu.setStatus(BlogStatus.DISABLE.getStatus());
        categoryMenu.setUpdateTime(new Date());
        categoryMenuMapper.updateByPrimaryKeySelective(categoryMenu);
        cacheService.deleteResourceList("*");
        return ResultUtils.successWithMessage(MessageConstant.DELETE_SUCCESS);
    }

}
